package com.boarsoft.boar.gateway.web.handler;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.RejectedExecutionException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.boarsoft.config.core.Configable;
import com.boarsoft.soagov.config.SvcConfig;
import com.boarsoft.soagov.route.ServiceRouter;
import com.boarsoft.soagov.spy.SpyData;
import com.boarsoft.soagov.spy.SvcSpy;
import com.boarsoft.webapp.HttpServiceHandler;
import com.boarsoft.webapp.mock.HttpMocker;

/**
 * 标准的HTTP服务处理
 * 
 * @author Mac_J
 *
 */
public class SimpleHttpHandlerImpl implements HttpServiceHandler, Configable {
	/** 默认使用随机路由 */
	protected Map<String, ServiceRouter<?>> routerMap = new ConcurrentHashMap<String, ServiceRouter<?>>();
	/** */
	protected Map<String, HttpMocker> mockerMap = new ConcurrentHashMap<String, HttpMocker>();
	/** */
	protected SvcSpy svcSpy;

	@Override
	public void config() {
		// 配置每一个router
		for (ServiceRouter<?> sr : routerMap.values()) {
			sr.config();
		}
	}

	@Override
	public boolean process(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
		// 取服务编号service key
		String sk = req.getHeader("service");
		// ServiceRouter router = routerMap.get(sc);

		// 服务治理埋点，如果svcSpy不为空，且服务状态为关闭，则尝试使用mocker
		if (svcSpy != null) {
			SpyData sd = svcSpy.getSpyData(sk);
			int status = svcSpy.checkStatus(sd);
			// 检查服务的开关状态，与是否开启了结果模拟
			if (status == SvcConfig.STATUS_DISABLE) {
				// 如果服务被关闭，直接抛出拒绝执行异常
				throw new RejectedExecutionException(sk);
			}
			if (status == SvcConfig.STATUS_MOCKING) {
				// 如果开启了结果模拟功能，通过服务治理插件调用模拟器，返回模拟的结果
				if (mockerMap.containsKey(sk)) {
					HttpMocker mocker = mockerMap.get(sk);
					if (mocker.mock(req, rsp)) {
						return true;
					}
				}
				if (svcSpy.mock(sk)) {
					return true;
				}
				return true;
			}
		}
		return true;
	}

	public SvcSpy getSvcSpy() {
		return svcSpy;
	}

	public void setSvcSpy(SvcSpy svcSpy) {
		this.svcSpy = svcSpy;
	}

	public Map<String, ServiceRouter<?>> getRouterMap() {
		return routerMap;
	}

	public void setRouterMap(Map<String, ServiceRouter<?>> routerMap) {
		this.routerMap = routerMap;
	}

	public Map<String, HttpMocker> getMockerMap() {
		return mockerMap;
	}

	public void setMockerMap(Map<String, HttpMocker> mockerMap) {
		this.mockerMap = mockerMap;
	}
}